/*
require  util.js
require  tabmenu.js
require  core1.1
require  dataColumn.js
require  tickerList.js
 */
if (!Util.isValid(QSAPI)) {
	var QSAPI = {
		Widget : {}
	};
} else if (!QSAPI.Widget) {
	QSAPI.Widget = {};
}
QSAPI.Widget.Watchlist = function(container, config, callback, sdkid) {
	this.config = {
		fixHeight : true,
		showInvalid: false,
		dataType:"pull",
		// grid config
		remove : true,// whether the grid display the remove column
		highlightColumn : false,
		isFormat : true,
		needUnit : false,
		numberSeparate : "",
		refreshRate:10,
		sortable : true,
		checkFields: ["AUTH","GKEY"],
		alternateRow : true,
		cellResize : false,
		cellRearrange : false,
		initwidth:500,
        initheight:500,
        userCurrency:"usercur",
        showSummaryPlugin:false,
        showSummary:true,
        summaryCalcMethod:{
            "TC":"TC",
            "P/L":"P/L",
            "P/Lpc":function(data){return data["P/L"]/data["TC"];},
            "MarketValue":"MarketValue",
            "Comm":"Comm"
        },
        summaryIsShow:true,
        summaryHeight:35,
		rowDragable : false,
		rowDropable : false,
		groupBy : null,// default group by sector
		viewKey : ['Symbol','Name','LastPrice','Chg','Chg%','Volume','RVolume'],// grid columns
		// layout config
		displayLayout : GB_WL_LAYOUT.LIST,// default layout
		// tabmenu config
		showTab : true,
		openedList : [],// tabmenu list
		defaultWatchlist :GB_WL_MS.DOW,// default active/open watchlist
		tabclosable : false,
		tabContainer: null
	};
	//static variable
	this.staticValue = {
		tabMenuHeight :28
	};
	this.referID = {
		PID : {
			field:GB_WL_KEY.PID,
			errorMessage:"No Morningstar ID"
		},
		AUTH:{
			field:GB_WL_KEY.VALID,
			errorMessage:"No Entitlement"
		},
		GKEY: {
			field:GB_WL_KEY.GKEY,
			errorMessage:"No Tenfore Info"
		}
	};
	this.watchlistProperty={
		ID:"id",
		NAME:"name",
		TYPE:"type",
		DATA:"data",
		CONFIG:"config"
	};
	this.watchlistType={
		SIMPLE:'wl',
		COMPLEX:'pf'
	};
	this.subscribeID = sdkid;
	this.container = container;
	this.el = null;
	this.tab = null;
	this.summaryWidget=null;
	this.load=0;
	this.commonColumns = false;// tag whether display list colnumns
	$.extend(true, this.config, config);
	if(config.viewKey){
		this.config.viewKey = config.viewKey.slice();
	}
	this.callback = {};
	$.extend(true, this.callback, callback);
	this._createTickerList();
};
QSAPI.Widget.Watchlist.prototype = {
	_createTickerList : function() {
		var self = this, html = '<div class="rtq-simpleWL"><div class="rtq-wl-tab-wrap clearfix"></div><div class="rtq-wl-wrap"></div></div>';
		this.el = $(html).appendTo(this.container);
		var tickerlistConfig = {
			displayLayout : this.config.displayLayout,
			autoRefresh: !this.config.showSummary,
			groupBy : this.config.displayLayout.indexOf('group') > -1 ? this.config.groupBy
					: null,
			autoHeight : this.config.fixHeight ? false : true,
			remove : this.config.remove,
			rowDragable : this.config.rowDragable,
			rowDropable : this.config.rowDropable,
			dataType : this.config.dataType,
			showInvalid : this.config.showInvalid,
			initwidth:this.config.initwidth,
			sortable : this.config.sortable,
			viewKey:this.config.viewKey,
			userCurrency:this.config.userCurrency,
			summaryCalcMethod:this.config.summaryCalcMethod,
			summaryCalcMethod:this.config.summaryCalcMethod,
			alternateRow:this.config.alternateRow,
			realVolume: this.config.realVolume,
			cellResize : this.config.cellResize,
			cellRearrange : this.config.cellRearrange,
			showFooter:this.config.showSummary&&!this.config.showSummaryPlugin,
			highlightColumn : this.config.highlightColumn,
			subscribeInvisibleTickers:this.config.showSummary,//if show summary, that subscribe invisible rows.
			headerContextMenu : false,
			isFormat : this.config.isFormat,
			isUnit : this.config.needUnit,
			numberSeparate : this.config.numberSeparate
		}, tickerCallback = {
			onLoad : function(para) {
				if (Util.isFunction(self.callback.onLoad)) {
					self.callback
							.onLoad({
								component : "watchlist",
								height : para.height
										+ (self.config.showTab ? self.staticValue.tabMenuHeight
												: 0),
								width : para.width,
								minWidth : para.minWidth
							});
				}
			},
			onRowDoubleClick : function(e, watchlistDataItem) {
				if (Util.isFunction(self.callback.onRowDoubleClick)) {
					var gkey = row.data.gkey;
					self.callback.onRowDoubleClick(e,watchlistDataItem[GB_WL_KEY.ITEM]);	
				}
			},
			onStateChange:function(configName,value){
				self._onChangeStatusHandler(configName,value);
			},
			onRowRemove : function(watchlistId, watchlistDataItem) {
				if (Util.isFunction(self.callback.onRowRemove)) {
					self.callback.onRowRemove(watchlistId,watchlistDataItem[GB_WL_KEY.ITEM]);
				}
			},
			onRowSelected : function(e, watchlistDataItem) {
				if (Util.isFunction(self.callback.onRowSelected)) {
					self.callback.onRowSelected(e,watchlistDataItem[GB_WL_KEY.ITEM]);	
				}
			},
			onHeightChange : function(para) {
				if (Util.isFunction(self.callback.onHeightChange)) {
					self.callback
							.onHeightChange({
								component : "watchlist",
								height : para.height
										+ (self.config.showTab ? self.staticValue.tabMenuHeight
												: 0),
								width : para.width
							});
				}
			},
			onRowDragStart : function(e, proxy, watchlistDataItem) {
				if (Util.isFunction(self.callback.onRowDragStart)) {
					self.callback.onRowDragStart(e, proxy);
				}
			},
			onCellSort:function(cellkey,order){
				//self._onChangeStatusHandler("sortCell", cellkey);
				//self._onChangeStatusHandler("sortOrder", order);
			},
			afterRebindData:function(){
				if(self.config.summaryIsShow){
					self.showSummary();
				}else{
					self.hideSummary();
				}
			}
		};

		if (Util.isFunction(this.callback.onRowMouseover)) {
			tickerCallback["onRowMouseover"] = function(e, watchlistDataItem) {
				self.callback.onRowMouseover(e,watchlistDataItem[GB_WL_KEY.ITEM]);
			};
		}
		if (Util.isFunction(this.callback.onRowMouseout)) {
			tickerCallback["onRowMouseout"] = function(e, watchlistDataItem) {
				self.callback.onRowMouseout(e,watchlistDataItem[GB_WL_KEY.ITEM]);
			};
		}
		if (this.config.headMapCols) {
			tickerlistConfig.headMapCols = this.config.headMapCols;
		}
		if (this.config.width) {
			tickerlistConfig.initwidth = this.config.width;
		} else if (this.config.initwidth) {
			tickerlistConfig.initwidth = this.config.initwidth;
		}
		if(Util.isValid(tickerlistConfig.initwidth,true,true)){
			this.el.css({
				width : tickerlistConfig.initwidth
			});
		}
		if(this.config.height){
			tickerlistConfig.initheight = this.config.height-
			(this.config.showTab ? this.staticValue.tabMenuHeight:0);
		}else if (this.config.initheight) {
			tickerlistConfig.initheight = this.config.initheight-
			(this.config.showTab ? this.staticValue.tabMenuHeight:0)-
			(this.config.summaryIsShow&&this.config.showSummary&&this.config.showSummaryPlugin?this.config.summaryHeight:0);
		}
		this.tickerlist = new QSAPI.Widget.Tickerlist(this.el
				.find(".rtq-wl-wrap"), tickerlistConfig, tickerCallback,this.subscribeID);
		this.commonColumns = true;
		if (this.config.rowDropable) {
			var watchlistDrop = new Util.Dropable(this.el, {
				onDrop : function(e, proxy) {
					if(proxy.rowDrag) {proxy.rowDrag= false; return;}
					if (proxy.widgetID == self.subscribeID) {// from different
						if (Util.isFunction(self.callback.onDrop)) {
							self.callback.onDrop(e, proxy);
						} else {
							if (proxy.item) {
								self.acceptTicker([proxy.item]);
							}
						}
					}
					proxy.widgetID = null;
				},
				onEnter : function(e, proxy) {
					if (proxy.item) {
						proxy.addClass("rtq-dd-drop-yes");
					} else {
						proxy.removeClass("rtq-dd-drop-yes");
					}
				},
				onOut : function(e, proxy) {
					
				}
			}, {
				group : 'gridDDGroup'
			});
		}
	},
	_convertClientData:function(datasource,callback){
		var self = this;
		GB_WLDM.getWatchlistDataItems(datasource,function(watchlistDataItems){
			self._checkTicker(watchlistDataItems, self.config.checkFields);
			if(Util.isFunction(callback)){
				callback(watchlistDataItems);
			}
		});
	},
	_checkTicker : function(watchlistDataItems,needCheckIDs) {//for sdk
		var invalid = {},isValid=true,tempID = null,needCheck=null,tempTickerObject=null,validItems=[];
		for ( var i = 0, l = watchlistDataItems.length; i < l; i++) {
			tempID = null;
			isValid=true;
			tempTickerObject = watchlistDataItems[i][GB_WL_KEY.ITEM].getTickerObject();
			for(var j=0,m=needCheckIDs.length;j<m;j++){
				needCheck = this.referID[needCheckIDs[j]];
				tempID = tempTickerObject[GB_WL_KEY.FIELD](needCheck.field);
				if(!Util.isValid(tempID,true,true,true)&&!tempID){//false
					if(!invalid[needCheck["errorMessage"]]){
						invalid[needCheck["errorMessage"]]=[];
					}
					invalid[needCheck["errorMessage"]].push(tempTickerObject);
					isValid=false;
					break;
				}
			}
			if(isValid){
				validItems.push(watchlistDataItems[i]);
			}
		}
		if (Util.isFunction(this.callback.processInvalid)&&!$.isEmptyObject(invalid)) {
			this.callback.processInvalid(invalid);
		}
	},
	_onDeactiveHandle:function(){
		this.stopSubscribe();//subscribe all ticker
		if (Util.isFunction(this.callback.onDeActive)) {
			this.callback.onDeActive(tab);
		}
	},
	_onChangeStatusHandler:function(configName,value){
		if (Util.isFunction(this.callback.onStateChange)) {
			this.callback.onStateChange(configName,value);
		}
	},
	_getTabData:function(wllist) {
		var wl_alias = '', d = [], wl_info = {};
		if(this.config.openedList.length==0){
			this.config.openedList=[this.config.defaultWatchlist];
		}
		for (var i = 0, l = this.config.openedList.length; i < l; i++) {
			wl_alias = this.config.openedList[i];
			if(Util.isValid(wl_alias,true,true)){
				for(var j = 0, m = wllist.length; j < m; j++){
					wl_info = wllist[j];
					if(wl_alias == wl_info[this.watchlistProperty.ID]){
						d.push({
							txt : wl_info[this.watchlistProperty.NAME],
							id :  wl_alias,
							type: wl_info[this.watchlistProperty.TYPE],
							config: wl_info[this.watchlistProperty.CONFIG],
							closable : this.config.tabclosable
						});
						break;
					}
				}
			}
		}
		this.cacheTabData=d;
	},
	_onActiveHandle : function(tab) {
		if(Util.isValid(tab.id,true,true,true)){
			this.tabID = tab.id;
			this._reBindTickers(this.tabID,tab.config);
			if (Util.isFunction(this.callback.onActive)) {
				this.callback.onActive(tab);
			}
			this._onChangeStatusHandler("watchlistId", this.tabID);
		}
	},
	_reBindTickers:function(id,config){
		this.tickerlist.setWatchlistId(id);//it is necessary
		var self = this;
		this.showLoading();
		GB_WLDM.getWatchlistData(id,function(watchlistData){
			if(Util.isValid(config,true,true)){
				self.tickerlist.setConfig(config);
			}
			self.tickerlist.reBindData(watchlistData.getItems());
			self.hideLoading();
		});
	},
	_calcSummary:function(){
		this.showLoading();
		if(this.config.showSummary&&this.config.summaryIsShow){
			var self=this;
			this.tickerlist.calcSummary(function(o){
				self.hideLoading();
				if(self.config.showSummaryPlugin){
					self.summaryWidget.updateSummary(o);//{TC:'0.00',PL:'0.00',PLP:'0.00',MV:'0.00',DPL:'0.00',DPLP:'0.00'};
				}
			});
		}
	},
	_genTab : function() {
		var tabContainer = this.el.find(".rtq-wl-tab-wrap"), self = this;
		// bind tabmenu
		if (this.config.showTab) {
			this.tab = new Util.TabMenu(
					this.config.tabContainer ? this.config.tabContainer
							: tabContainer, this.cacheTabData, {
						onActive : function(tab) {
							self._onActiveHandle(tab);
						},
						onDeActive : function(tab) {
							self._onDeactiveHandle(tab);
						}
					}, {
						width : 80,
						tabsList : false,
						isExcuteCallbackAtInit : true,
						activeTabId : this.config.defaultWatchlist,
						plusSymbol : false,
						rearrange : false
					});
		} else {
			tabContainer.hide();
			this._onActiveHandle(this.cacheTabData[0]);
		}
		this.staticValue.tabMenuHeight = tabContainer.height();
	},
	init : function() {
		var self=this;
		this.showLoading();
		GB_WLWM.register(this);
		if(this.config.showSummary){//if show summary function, the data type only support pull
			this.config.dataType = "pull";
			if(this.config.showSummaryPlugin){
				this.summaryWidget = new QSAPI.Widget.WatchlistSummary(this.el,{height:this.config.summaryHeight},{onClickRefresh:function(){
					self.summaryWidget.disableRefreshButton();
					self._calcSummary();
					Util.DelayRun('summaryRefresh.watchlist', function(){
						self.summaryWidget.ableRefreshButton();
					}, self.config.refreshRate*1000, self);
				}});
			}
		}
		GB_WLDM.getWatchlistList(null,function(wllist){
			self._getTabData(wllist);
			self._genTab();
			self.hideLoading();
		});
	},
	loadTickers : function(tickerlist) {//tickerObject array,tickerObject from DB
		this.tickerlist.stopSubscribe();
		var watchlist = {};
		watchlist[this.watchlistProperty.ID]=this.tabID;
		watchlist[this.watchlistProperty.DATA] = tickerlist;
		GB_WLDM.deleteItems(this.tabID);
		GB_WLDM.setWatchlistData([watchlist]);
		this._reBindTickers(this.tabID);
	},
	showSummary:function(){
		if(this.config.showSummary){
			if(!this.config.summaryIsShow){
				this._onChangeStatusHandler("summaryIsShow",true);
				this.config.summaryIsShow=true;
			}
			if(this.config.showSummaryPlugin){
				this.summaryWidget.show();
			}else{
				this.tickerlist.showFooter();
			}
			this.changeOutSize();
			this._calcSummary();
		}
	},
	hideSummary:function(){
		if(this.config.showSummary){
			if(this.config.summaryIsShow){
				this.config.summaryIsShow=false;
				this._onChangeStatusHandler("summaryIsShow",false);
			}
			if(this.config.showSummaryPlugin){
				this.summaryWidget.hide();
			}else{
				this.tickerlist.hideFooter();
			}
			this.changeOutSize();
		}
	},
	acceptTicker : function(tickerlist) { //tickerObject array,tickerObject from User custom
		var self=this;
		this._convertClientData(tickerlist,function(watchlistDataItems){
			self.tickerlist.addTickers(watchlistDataItems);
		});
	},
	saveTickers:function(id){
		return GB_WLDM.saveWatchlist(id);
	},
	saveConfig:function(){  // save the config for watchlist.
        /* save the watchlist in tabmenu*/
        var id=null,newOpenedList = [],data=this.config.showTab?this.tab.getIdList():this.config.openedList;
        for(var i=0,l=data.length;i<l;i++){
         	id=data[i];
            newOpenedList.push(id);
        }
        var config = {
            defaultWatchlist: this.tabID, 
            viewKey: this.getColumns(),  // the customize view id is managed by watchlist object.
            displayLayout: this.config.displayLayout,// the displayLayout is managed by tickerList object.
            groupBy: this.config.groupBy,  //the group by field is managed by tickerList object.
            summaryIsShow:this.config.showSummary&&this.config.summaryIsShow
            //sortCell: this.getLastSortCell(), // the sort cell field. managed by grid.
            //sortOrder: this.getLastSortOrder(),  // the orientation of sort: desc or asc. managed by grid.
            //openedList: newOpenedList
        };
        return config;
    },
    stopSubscribe:function(){
    	this.tickerlist.stopSubscribe();
    },
    getColumns:function(){
    	return this.tickerlist.getColumnsView();
    },
	getSortableColumns : function() {
		return this.tickerlist.getSortColumns();
	},
	getLastSortCell : function() {
		return this.tickerlist.getlastSortCellKey();
	},
	getLastSortOrder : function() {
		return this.tickerlist.getSortOrder();
	},
	changeViewType : function(v) {
		if (this.config.displayLayout != v) {
			this.config.displayLayout = v;
			if (this.config[v + "_viewKey"]) {
				this.commonColumns = false;
				this.tickerlist.setColumns(this.config[v + "_viewKey"]);
			} else if (!this.commonColumns) {
				this.commonColumns = true;
				this.tickerlist.setColumns(this.config["viewKey"]);
			}
			this.tickerlist.changeViewType(v);
		}
	},
	setColumns:function(viewKey,layout){
		if (!Util.isValid(layout,true,true,true))
			layout = GB_WL_LAYOUT.LIST;
		if (this.config.displayLayout == layout) {// other
			if (layout != GB_WL_LAYOUT.LIST) {
				this.commonColumns = false;
				this.config[layout + "_viewKey"] = viewKey;
				this.tickerlist.setColumns(viewKey);
			} else {
				this.commonColumns = true;
				this.config["viewKey"] = viewKey;
				this.tickerlist.setColumns(this.config["viewKey"]);
			}
		} else {
			if (layout == GB_WL_LAYOUT.LIST) {//
				this.config["viewKey"] = viewKey;
				if (!this.config[this.layout + "_viewKey"]) {
					this.commonColumns = true;
					this.tickerlist.setColumns(viewKey);
				}
			} else {
				this.config[layout + "_viewKey"] = viewKey;
			}
		}
	},
	refreshWatchlist:function(){
		if(!this.disableRefresh){
			this.disableRefresh=true;
			if(this.config.showSummary){
				this.tickerlist.refresh();
				this._calcSummary();
			}
			var self = this;
			Util.DelayRun('summaryRefresh.watchlist', function(){
                self.disableRefresh=false;
        	}, this.config.refreshRate*1000,self);
		}
	},
	setLoadingHandle:function(showHandle,hiddenHandle){
        var self=this;
        if(Util.isFunction(showHandle)){
            this.showLoading=function(){
                if(self.load==0){
                   showHandle.apply(self);
                }
                self.load++;
            };
        }
        if(Util.isFunction(hiddenHandle)){
            this.hideLoading=function(){
                self.load--;
                if(self.load==0){
                   hiddenHandle.apply(self);
                }
            };
        }
        this.tickerlist.setLoadingHandle(showHandle,hiddenHandle);
    },
    hideLoading:function(){},
    showLoading:function(){},
	updateData : function(tickerObject, needupdatefiled, needFlash) {
		this.tickerlist.updateData(tickerObject, needupdatefiled, needFlash);
	},
	groupBy : function(dataindex, callback) {
		this.tickerlist.groupBy(dataindex, callback);
	},
	changeOutSize : function(w, h) {
		w = w ||this.config.initwidth ||  this.container.width();
		h = h ||this.config.initheight ||  this.container.height();
		this.el.css({
			width : w
		});
		this.config.initwidth=w;
		this.config.initheight=h;
		this.tickerlist.changeOutSize(
			w,
			h- (this.config.showTab ? this.staticValue.tabMenuHeight: 0)-(this.config.summaryIsShow&&this.config.showSummary&&this.config.showSummaryPlugin?this.config.summaryHeight:0)
		);
	},
	clear : function() {
		GB_WLWM.unregister(this);
		for ( var p in this) {
			if (!p || p == 'clear') {
				continue;
			}
			this[p] = null;
			delete this[p];
		}
	},
	show : function() {
		this.el.show();
	},
	hide : function() {
		this.el.hide();
	}
};
